package com.hrt.db;

import com.btcode.common.MyLog;
import com.btcode.common.PropertiesUnit;
import com.btcode.db.config.DataBaseConfig;
import com.btcode.db.config.DataBaseType;
import com.btcode.db.executer.DefaultDataExecuterFactory;
import com.btcode.db.executer.IDataExecuter;
import com.btcode.db.executer.IDataExecuterFactory;
import com.btcode.log.ILog;
import com.btcode.orm.cache.EhcacheExecuter;
import com.btcode.orm.cache.IORMCacheExecuter;
import com.btcode.orm.conver.DefaultModelConver;
import com.btcode.orm.conver.DefaultValueConver;
import com.btcode.orm.conver.IValueConver;
import com.btcode.orm.executer.DefaultORMExecuter;
import com.btcode.orm.executer.IORMExecuter;
import com.hrt.datasender.web.WebMain;

public final class DBManager {

    private ILog log;

    private static volatile DBManager instance;

    private static volatile IDataExecuter dataExecuter;

    private static volatile IORMExecuter ormExecuter;

    // access数据库连接
    private static volatile IDataExecuter accessExecuter;

    private DBManager() {

    }

    public static DBManager getInstance() {
        if (instance == null) {
            synchronized (DBManager.class) {
                if (instance == null) {
                    instance = new DBManager();
                }
            }
        }
        return instance;
    }

    /**
     * @return
     * @author Fan 18/7/24 access数据库连接
     */
    public IDataExecuter getRealAccessExecuter() {
        if (accessExecuter == null) {
            synchronized (DBManager.class) {
                if (accessExecuter == null) {
                    String connectStr = PropertiesUnit.getValue("conf", "accessDbConnStr");

                    DataBaseConfig dbConfig = new DataBaseConfig();
                    dbConfig.setConnectionString(connectStr);
                    dbConfig.setDbType(DataBaseType.access);
                    dbConfig.setDirverClass("com.hxtt.sql.access.AccessDriver");
                    //dbConfig.setDirverClass("net.ucanaccess.jdbc.UcanaccessDriver");
                    IDataExecuterFactory deFactory = new DefaultDataExecuterFactory();
                    ConnectionGetterForAccess connectionGetter = new ConnectionGetterForAccess(dbConfig);
                    accessExecuter = deFactory.getDataExecuter(dbConfig, connectionGetter);

                    log = MyLog.getInstance().getLogger(accessExecuter.getClass().getName());
                    accessExecuter.setLog(log);
                }
            }
        }

        return accessExecuter;
    }

    public IDataExecuter getRealDataExecuter() {
        if (dataExecuter == null) {
            synchronized (DBManager.class) {
                if (dataExecuter == null) {
                    /**
                     * 根据配置不同，采用不同的数据库连接
                     */
                    if("mysql".equals(WebMain.DBTYPE)){
                        String connectStr = PropertiesUnit.getValue("conf", "mysqlDbConnStr");
                        String passWord = PropertiesUnit.getValue("conf", "mysqlDbPassWord");
                        if(passWord==null){
                            passWord = "data_sender";
                        }
                        DataBaseConfig dbConfig = new DataBaseConfig();
                        dbConfig.setConnectionString(connectStr);
                        dbConfig.setDbName("data_sender");
                        dbConfig.setUserName("root");
                        dbConfig.setPassword(passWord);
                        dbConfig.setDbType(DataBaseType.mysql);
                        dbConfig.setDirverClass("com.mysql.cj.jdbc.Driver");
                        dbConfig.setUsePool(false);
                        IDataExecuterFactory deFactory = new DefaultDataExecuterFactory();
                        ConnectionGetterForMysql connectionGetter = new ConnectionGetterForMysql(dbConfig);
                        dataExecuter = deFactory.getDataExecuter(dbConfig, connectionGetter);

                        log = MyLog.getInstance().getLogger(dataExecuter.getClass().getName());
                        dataExecuter.setLog(log);
                    }
                    else {
                        String connectStr = PropertiesUnit.getValue("conf", "sqlletDbConnStr");

                        DataBaseConfig dbConfig = new DataBaseConfig();
                        dbConfig.setConnectionString(connectStr);
                        dbConfig.setDbName("orcl");
                        dbConfig.setUserName("water");
                        dbConfig.setPassword("water");
                        dbConfig.setDbType(DataBaseType.sqllet);
                        dbConfig.setDirverClass("org.sqlite.JDBC");
                        dbConfig.setUsePool(false);
                        IDataExecuterFactory deFactory = new DefaultDataExecuterFactory();
                        ConnectionGetterForSQLLit connectionGetter = new ConnectionGetterForSQLLit(dbConfig);
                        dataExecuter = deFactory.getDataExecuter(dbConfig, connectionGetter);

                        log = MyLog.getInstance().getLogger(dataExecuter.getClass().getName());
                        dataExecuter.setLog(log);
                    }
                }
            }
        }

        return dataExecuter;
    }

    public IORMExecuter getRealORMExecuter() {
        if (ormExecuter == null) {
            synchronized (DBManager.class) {
                if (ormExecuter == null) {
                    /**
                     * 根据配置不同，采用不同的数据库连接
                     */
                    IORMCacheExecuter ormCache = new EhcacheExecuter();
                    IDataExecuter dataExecuter = getDataExecuter();
                    IValueConver valueCover = new DefaultValueConver();
                    if("mysql".equals(WebMain.DBTYPE)){
                        ormExecuter = new DefaultORMExecuter(dataExecuter, new DefaultModelConver(), ormCache, valueCover);
                    }
                    else {
                        ormExecuter = new ORMExecuterForSQLLit(dataExecuter, new DefaultModelConver(), ormCache, valueCover);
                    }
                }
            }
        }

        return ormExecuter;
    }

    public static IDataExecuter getDataExecuter() {

        IDataExecuter dataExecuter = DBManager.getInstance().getRealDataExecuter();
        return dataExecuter;

    }

    public static IDataExecuter getAccessExecuter() {

        IDataExecuter dataExecuter = DBManager.getInstance().getRealAccessExecuter();
        return dataExecuter;

    }

    public static IORMExecuter getORMExecuter() {

        IORMExecuter ormExecuter = DBManager.getInstance().getRealORMExecuter();
        return ormExecuter;

    }

}
